﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GraphGeneric;

namespace GraphGenericTestApp
{
    public class DirectedGraph : IGraph<string, string>
    {

       
      

        private Dictionary<string, INode<string, string>> m_nodeDictionary = new Dictionary<string, INode<string, string>>();
        private List<IEdge<string, string>> m_edges = new List<IEdge<string, string>>();

        #region IGraph<string,string> Members

        public IEnumerable<INode<string, string>> AllNodes
        {
            get { return m_nodeDictionary.Values; }
        }

        public INode<string, string> GetNode(string value)
        {
            INode<string, string> node;
            m_nodeDictionary.TryGetValue(value, out node);
            return node;
        }

        public INode<string, string> AddNode(string value)
        {
            INode<string, string> node;
            if (!m_nodeDictionary.TryGetValue(value, out node))
            {
                node = new Node(value);
                m_nodeDictionary.Add(value, node);
            }
            return node;
        }

        public IEdge<string, string> AddEdge(string fromValue, string toValue)
        {
            return AddEdge(GetNode(fromValue), GetNode(toValue));
        }

        public IEdge<string, string> AddEdge(INode<string, string> fromNode, INode<string, string> toNode)
        {
            if (fromNode == null || toNode == null)
                return null;

            IEdge<string, string> edge = fromNode.Edges.FirstOrDefault(e => e.ToNode.Value == toNode.Value);
            if (edge == null)
            {
                edge = new Edge(fromNode, toNode);
                fromNode.AddEdge(edge);
            }

            return edge;
        }

        #endregion
    }

    public class Node : INode<string, string>
    {
        public Node(string value)
        {
            m_value = value;
        }
        public override string ToString()
        {
            return Value;
        }
        private string m_value;
        private List<IEdge<string, string>> m_edges = new List<IEdge<string, string>>();

        #region INode<string,string> Members

        public string Value
        {
            get { return m_value; }
        }

        public IEnumerable<IEdge<string, string>> Edges
        {
            get { return m_edges; }
        }

        public void AddEdge(IEdge<string, string> edge)
        {
            m_edges.Add(edge);
        }

        #endregion
    }

    public class Edge : IEdge<string, string>
    {
        public Edge(INode<string, string> fromNode, INode<string, string> toNode)
        {
            m_fromNode = fromNode;
            m_toNode = toNode;
        }
        public override string ToString()
        {
            return string.Format("{0} -- {1}", FromNode, ToNode);
        }
        private INode<string, string> m_fromNode;
        private INode<string, string> m_toNode;
        private string m_weight = "No Weight";
        private bool m_isDirected = true;

        #region IEdge<string,string> Members

        public INode<string, string> FromNode
        {
            get { return m_fromNode as Node; }
        }

        public INode<string, string> ToNode
        {
            get { return m_toNode as Node; }
        }

        public string Weight
        {
            get { return m_weight; }
        }

        public bool IsDirected
        {
            get { return m_isDirected; }
        }

        #endregion
    }


}
